package com.zhangyj.entitis;

import java.io.File;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.zhangyj.cache.CacheEngine;
import com.zhangyj.cache.DataCacheManager;
import com.zhangyj.util.Tools;

/**
 * 
 * @author zhangyj
 * 
 */

public class SelectorInfo implements Serializable {
	private static final long serialVersionUID = 855199836983354938L;
	private static final String CACHEKEY = "selector";
	private String name;
	private String sql;
	private String filterName = "";
	private String caption = "Selector";
	private Set<String> hiddenFields;
	private Set<String> returnFields;
	private Map<String, String> lables;
	private boolean mulitSelect = false;

	// 分页信息
	private boolean hasPagination = false;
	private int pageSize = 0;
	private String orderTable = null;
	private String orderField = null;
	private String countSql = null;
	private boolean isDesc = false;

	@SuppressWarnings("deprecation")
	public static SelectorInfo getInfo(HttpServletRequest request) throws Exception {
		CacheEngine engine = DataCacheManager.getCacheEngine();
		String key = request.getParameter("selector");
		SelectorInfo selector = (SelectorInfo) engine.getObject(CACHEKEY, key);
		if (selector == null) {
			synchronized (engine) {
				if (selector == null) {
					String path = request.getRealPath("/WEB-INF/config/selector.xml");
					SAXReader reader = new SAXReader();
					Document doc = reader.read(new File(path));
					Element root = doc.getRootElement();
					Iterator<?> iterator = root.elementIterator();
					while (iterator.hasNext()) {
						SelectorInfo s = new SelectorInfo((Element) iterator.next());
						engine.putObject(CACHEKEY, s.getName(), s);
						if (s.getName().equals(key)) {
							selector = s;
						}
					}
				}
			}
		}
		return selector;
	}

	private SelectorInfo(Element selector) {
		this.name = selector.elementText("name");
		this.sql = selector.elementText("sql");
		Element filter = selector.element("filter");
		if (filter!= null) {
			this.filterName = filter.getTextTrim();
		}
		this.initLable(selector.element("labels"));
		Element item = selector.element("caption");
		if (item != null)
			this.caption = item.getText();

		item = selector.element("multiselect");
		if (item != null) {
			String text = item.getText().trim().toLowerCase();
			this.mulitSelect = "true".equals(text) || "y".equals(text) || "yes".equals(text);
		}

		item = selector.element("hiddenfield");
		if (item != null) {
			String text = item.getText();
			if (text != null) {
				text = text.toLowerCase();
				this.hiddenFields = Tools.strSplitToSet(text, ",");
			}
		}

		item = selector.element("returnfield");
		if (item != null) {
			String text = item.getText();
			if (text != null) {
				text = text.toLowerCase();
				this.returnFields = Tools.strSplitToSet(text, ",");
			}
		}
		// 分页信息
		item = selector.element("pagnation");
		if (item != null) {
			initPagnation(item);
		}
	}

	private void initLable(Element labels) {
		if (labels == null) {
			return;
		}
		Iterator<?> iters = labels.elementIterator();
		if (iters == null) {
			return;
		}
		lables = new HashMap<String, String>();
		while (iters.hasNext()) {
			Element label = (Element) iters.next();
			lables.put(label.attributeValue("name").trim().toLowerCase(), label.getText());
		}
	}

	// <size>20</size>
	// <countSql>select count(id) from user</countSql>
	// <orderTable></orderTable>
	// <orderField>name</orderField>
	private void initPagnation(Element paginationEle) {
		Element item = paginationEle.element("countsql");
		if (item != null) {
			this.hasPagination = true;
			this.countSql = item.getText();
		}
		item = paginationEle.element("size");
		if (item != null)
			this.pageSize = Tools.str2int(item.getText(), 0);

		item = paginationEle.element("order");
		if (item != null) {
			this.orderTable = item.attributeValue("table");
			this.orderField = item.attributeValue("field");
			this.isDesc = "true".equals(item.attributeValue("desc"));
		}
	}

	public String getName() {
		return name;
	}

	public String getCaption() {
		return caption;
	}

	public String getLable(String fieldName) {
		if (this.lables == null) {
			return fieldName;
		}
		String value = this.lables.get(fieldName.trim().toLowerCase());
		if (value != null) {
			return value;
		}
		return fieldName;
	}

	public String getSql() {
		return sql;
	}

	public boolean isHiddenField(String key) {

		return hiddenFields == null ? false : hiddenFields.contains(key.toLowerCase());
	}

	public boolean isReturnField(String key) {
		return returnFields == null ? false : returnFields.contains(key.toLowerCase());
	}

	public boolean isMulitSelect() {
		return mulitSelect;
	}

	public int getPageSize() {
		return pageSize;
	}

	public boolean isHasPagination() {
		return hasPagination;
	}

	public String getOrderTable() {
		return orderTable;
	}

	public String getOrderField() {
		return orderField;
	}

	public String getCountSql() {
		return countSql;
	}

	public boolean isDesc() {
		return isDesc;
	}

	public String getFilterName() {
		return filterName;
	}
	
}
